Computer databases are widely used by businesses to access data for performing business transactions, such as making a savings account deposit or a withdrawal, reserve or purchase an airline ticket, buy or sell a security, etc. Each of these business transactions rely on the integrity of the data in the databases; i.e., the balance in the savings account must reflect the correct amount after the deposit or withdrawal. While conventional database applications generally comprise "short transactions" running for a few milliseconds, new applications, such as computer-aided design may include "long" transactions, which have the possibility of running for days, or even for weeks.
The databases described in the business transactions above are generally accessed and modified by multiple concurrently-run computer programs. Each of these concurrently-run programs (hereinafter, referred to as "transactions") comprise a plurality of operations on the database elements. In order to increase efficiency, the operations of the concurrently-run transactions are interleaved. The outcome of interleaved transactions, of course, should be the same as the outcome of running the transactions serially. A system which promotes this property is referred to as "serializable."
Without some control mechanism, concurrent transactions may result in one transaction's operations affecting another transaction's operations by accessing (reading and/or writing) the same element of the database. Such interferences may result in erroneous data in the databases; i.e., they may affect the "consistency" of the database. Protocols presently exist to protect the consistency of the database while it is accessed by concurrently running transactions. One such protocol is a static two-phase locking scheme. The static two-phase locking scheme provides "locking" all the database elements to be accessed by a transaction, before any operation of the transaction is performed, thus preventing any other transactions from accessing and altering the database elements. The database elements are "unlocked" immediately following the end of the transaction. If a transaction "commits" after its last operation, all database elements retain their values as updated by the transaction. If a transaction is "aborted", all database elements return to their values before as they were before the transaction.
A similar protocol, a dynamic two-phase locking scheme, locks each data item to be accessed by the transaction immediately prior to each accessing operation, and then releases the locks on all the data items immediately following the last operation of the transaction.
Both the static and dynamic two-phase locking scheme exhibit a first phase, during which locks are acquired on required data items, and a second phase, during which all the locks are released. By locking the database elements, a form of scheduling is achieved, since only the transactions that have locked all of their required data items are executed to completion. Other transactions which require access to database elements locked by another program, must wait until the lock is released. In other words, the locking scheme in effect puts concurrently-run programs in serial execution form at the cost of reducing throughput. Thus, if a long transaction locks an element needed by one or more short transactions, the short transactions may wait days or weeks before executing.
The two-phase locking schemes are referred to as "pessimistic," since they assume that an inconsistency will result between two or more concurrent transactions. "Optimistic" concurrency control allows a transaction to proceed as if there were no conflict, and performs a validation check at the time of commit of the transaction. The system assigns a unique timestamp to a transaction when it first begins to run. The transaction has a consistent view of the database during its execution; at commit time, the database systems checks, based on the timestamp, whether this consistent view of the database has changed between the start and finish of the transaction. If the consistent view still holds, the transaction is committed; if not, the transaction is aborted.
This protocol also has disadvantages, particularly with long transactions, since a transaction will run to its end before the determination is made whether it will be aborted or committed. If aborted, the entire transaction will need to be re-executed, which is an inefficient use of processing time, especially when a long transaction must be re-executed.
Further, present day databases do not adequately provide for cooperative efforts between multiple users. In a cooperative transaction, the work done by the team should be an atomic (indivisible) transaction. Also, members of the team should be able to view and modify the other team member's intermediate results. Accordingly, a need has arisen for a consistency control scheme that increases throughput of both long and short transactions and supports cooperative efforts between multiple users.